package com.ticket.sass.common.file.service.impl;


import com.alibaba.fastjson.JSON;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import com.ticket.sass.common.exception.enums.ErrorCode;
import com.ticket.sass.common.exception.exception.BaseException;
import com.ticket.sass.common.file.config.QiNiuConfig;
import com.ticket.sass.common.file.enums.FileType;
import com.ticket.sass.common.file.model.FileMode;
import com.ticket.sass.common.file.service.FileService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

@Service("qnFileService")
public class QiNiuFileService implements FileService {

    private final static Logger logger = LoggerFactory.getLogger(FileService.class);

    @Autowired
    private QiNiuConfig qiNiuConfig;

    private Configuration qiNiuCfg;

    private UploadManager uploadManager;

    private BucketManager bucketManager;

    private Auth auth;

    @PostConstruct
    private void init() {
        try {
            QiNiuConfig.Region region = qiNiuConfig.getRegion();
            if (region == null) {
                region = QiNiuConfig.Region.HUABEI;
            }
            
            // 根据配置的区域选择不同的Region
            switch (region) {
                case HUADONG:
                    qiNiuCfg = new Configuration(Region.huadong());
                    break;
                case HUANAN:
                    qiNiuCfg = new Configuration(Region.huanan());
                    break;
                case BEIMEI:
                    qiNiuCfg = new Configuration(Region.beimei());
                    break;
                    // 默认华北
                default:
                    qiNiuCfg = new Configuration(Region.huabei());
            }
            uploadManager = new UploadManager(qiNiuCfg);
            auth = Auth.create(qiNiuConfig.getAccessKey(), qiNiuConfig.getSecretKey());
            bucketManager = new BucketManager(auth, qiNiuCfg);
        } catch (Exception e) {
            logger.error("文件工具类初始化异常：{}", e.getMessage());
        }
    }
    /**
     * 根据配置参数获取token
     * @return
     */
    @Override
    public String uptoken() {
        try {
            return auth.uploadToken(qiNiuConfig.getBuckets().get("default"));
        } catch (Exception e) {
            logger.error(":{} 获取千牛key异常:{}", qiNiuConfig.getBuckets().get("default"), e.getStackTrace().toString());
            throw new BaseException(ErrorCode.SERVER_ERROR, "获取千牛key异常");
        }
    }

    /**
     * 根据传入参数获取token
     * @param bucketName
     * @return
     */
    @Override
    public String uptoken(String bucketName, String accessKey, String secretKey) {
        try {
            return Auth.create(accessKey,secretKey).uploadToken(bucketName);
        } catch (Exception e) {
            logger.error(":{} 获取千牛key异常:{}", bucketName, e.getStackTrace().toString());
            throw new BaseException(ErrorCode.SERVER_ERROR, "获取千牛key异常");
        }
    }

    /**
     * 根据配置参数上传流类型文件
     * @param fileInputStream
     * @param fileName
     * @return FileMode 类型{"fileId":"", "fileName"：""}
     */
    @Override
    public FileMode uploadFile(InputStream fileInputStream, String fileName, FileType fileType) {
        return uploadFile(null, null, null, fileInputStream, fileName,fileType);
    }
    
    @Override
    public FileMode uploadFile(String fileUrl, String fileName) {
   
        try {
            // 创建 URL 对象
            URL url = new URL(fileUrl);
            
            // 打开连接
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            
            // 设置请求方法为 GET
            connection.setRequestMethod("GET");
            
            // 发送请求
            connection.connect();
            
            // 获取响应码
            int responseCode = connection.getResponseCode();
            
            // 如果响应码为 200，表示请求成功
            if (responseCode == HttpURLConnection.HTTP_OK) {
                // 获取响应的输入流
                InputStream inputStream = connection.getInputStream();

                // 在这里你可以使用 inputStream，如将其传递给你的 uploadFile 方法
                FileMode fileMode = uploadFile(null, null, null, inputStream, fileName, FileType.JPG);
                // 关闭连接
                connection.disconnect();
                
                return fileMode;
            } else {
                System.out.println("请求失败，响应码：" + responseCode);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        
        return null;
    }
    
    /**
     * 根据传入参数上传流类型文件
     * @param bucketName
     * @param fileInputStream
     * @param fileName
     * @return FileMode 类型{"fileId":"", "fileName"：""}
     */
    @Override
    public FileMode uploadFile(String bucketName, String accessKey, String secretKey, InputStream fileInputStream, String fileName, FileType fileType) {
        return uploadFile(bucketName, accessKey, secretKey, (Object) fileInputStream, fileName,fileType);
    }

    /**
     * 根据配置参数上传文件类型文件
     * @param file
     * @param fileName
     * @return FileMode 类型{"fileId":"", "fileName"：""}
     */
    @Override
    public FileMode uploadFile(File file, String fileName,FileType fileType) {
        return uploadFile(null, null, null, file, fileName,fileType);
    }

    /**
     * 传入参数上传文件类型文件
     * @param file
     * @param fileName
     * @return FileMode 类型{"fileId":"", "fileName"：""}
     */
    @Override
    public FileMode uploadFile(String bucketName, String accessKey, String secretKey, File file, String fileName,FileType fileType) {
        return uploadFile( bucketName,  accessKey,  secretKey,  (Object) file,  fileName,fileType);
    }

    /**
     * 根据配置文件移动参数
     * @param fromKey
     * @param toKey
     * @return
     */
    @Override
    public boolean moveFile(String fromKey, String toKey) {
        try {
            return bucketManager.move(
                    qiNiuConfig.getBuckets().get("default"),
                    fromKey, qiNiuConfig.getBuckets().get("default"), toKey
            ).isOK();
        } catch (QiniuException e) {
            logger.error(e.response.toString());
            return false;
        }
    }

    /**
     * 根据闯入参数文件移动参数
     * @param fromKey
     * @param toKey
     * @return
     */
    @Override
    public boolean moveFile(String bucketName, String accessKey, String secretKey, String fromKey, String toKey) {
        try {
            BucketManager bucketManager = new BucketManager(Auth.create(accessKey,secretKey), qiNiuCfg);
            return bucketManager.move(
                    bucketName,
                    fromKey, bucketName, toKey
            ).isOK();
        } catch (QiniuException e) {
            logger.error(e.response.toString());
            return false;
        }
    }

    /**
     * 根据传入参数删除文件
     * @param bucketName
     * @param accessKey
     * @param secretKey
     * @param key
     * @return
     */
    @Override
    public boolean deleteFile(String bucketName, String accessKey, String secretKey, String key) {
        try {
            BucketManager bucketManager = new BucketManager(Auth.create(accessKey,secretKey), qiNiuCfg);
            return bucketManager.delete(qiNiuConfig.getBuckets().get("default"), key).isOK();
        } catch (QiniuException e) {
            logger.error(e.response.toString());
            return false;
        }
    }

    /**
     * 根据配置参数删除文件
     * @param key
     * @return
     */
    @Override
    public boolean deleteFile(String key) {
        try {
            return bucketManager.delete(qiNiuConfig.getBuckets().get("default"), key).isOK();
        } catch (QiniuException ex) {
            logger.error("调用千牛云删除文件异常：{}",ex.response.toString());
            return false;
        }
    }

    /**
     * 上传处理
     * @param bucketName
     * @param accessKey
     * @param secretKey
     * @param uploadObject
     * @param fileName
     * @return
     */
    private FileMode uploadFile(String bucketName, String accessKey, String secretKey, Object uploadObject, String fileName, FileType fileType) {
        //获取token
        String upToken = bucketName == null ? uptoken() : uptoken(bucketName, accessKey, secretKey);
        //上传
        Response response = null;
        String bodyStr = null;
        try {
            
            fileName = strIsEmpty(fileName) ? System.currentTimeMillis() + fileType.getCode() : fileName + fileType.getCode();
            response = uploadObject instanceof InputStream ?
                    uploadManager.put((InputStream) uploadObject, fileName, upToken, null, null) :
                    uploadManager.put((File) uploadObject, fileName, upToken);
            logger.info("上传千牛返回: {}", JSON.toJSON(response));
            bodyStr = response.bodyString();
        } catch (QiniuException ex) {
            logger.error("图片上传千牛异常:{}", ex.response.toString());
            throw new BaseException(ErrorCode.SERVER_ERROR, "图片上传千牛异常");
        }
        //返回处理
        if (response.isOK()) {
            DefaultPutRet putRet = JSON.parseObject(bodyStr, DefaultPutRet.class);
            return new FileMode(putRet.hash,putRet.key);
        } else {
            logger.error("千牛返回:{}", bodyStr);
            throw new BaseException(ErrorCode.SERVER_ERROR, "千牛服务器异常");
        }
    }
    public boolean strIsEmpty(String str) {
        return str == null || "".equals(str);
    }

}